package com.itlong.cloud.controller.system;

import com.itlong.cloud.POJO.PO.OperateUserInfoPO;
import com.itlong.cloud.POJO.PO.UserLoginLogPO;
import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.POJO.VO.operate.OperateUserLoginVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.abstracts.BaseController;
import com.itlong.cloud.annotation.LoggerInfo;
import com.itlong.cloud.constants.LogDescConstant;
import com.itlong.cloud.enumerate.SystemTypeEnum;
import com.itlong.cloud.enumerate.UserLoginDescEnum;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.OperateErrorCodeEnum;
import com.itlong.cloud.noncore.commons.IUserLoginLogServiceClient;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.user.operate.IOperateUserInfoServiceClient;
import com.itlong.cloud.utils.encrypt.Md5EncryptUtil;
import com.itlong.cloud.utils.encrypt.UserTokenUtil;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.List;

/**
 * <desc>
 *      用户登录控制器
 * </desc>
 *
 * @createDate 2017/09/26
 */
@RestController
@RefreshScope
public class OperateLoginController extends BaseController{
    @Autowired
    IOperateUserInfoServiceClient iOperateUserInfoServiceClient;

    @Autowired
    IUserLoginLogServiceClient iUserLoginLogServiceClient;

    @Value("${" + PlatformConstants.OPERATE_USER_PASSWORD_KEY + "}")
    String userPasswordKey;

    private static final Logger LOG = LoggerFactory.getLogger(OperateLoginController.class);

    /**
     * <desc>
     *      登录
     * </desc>
     *
     * @param userInfo 登录前的用户信息
     * @param request
     * @return
     * @author Jiaqi.X
     * @version 1.0
     */
    @LoggerInfo(identifer = "login")
//    @RequestMapping(value = "login",method = RequestMethod.POST)
    @ResponseBody
    public Object login(OperateUserInfoPO userInfo,HttpServletRequest request){
        MessageVO messageVO;
        try{
            userInfo=HttpProtocolUtil.parseRequestParamToDTO(OperateUserInfoPO.class,request);
            //解密密码
            String passwordStr = UserTokenUtil.getPassword(userInfo.getPassword(),userPasswordKey);
            //LOG.info("【运营登录userPasswordKey】:"+userPasswordKey);
            //LOG.info("【运营登录passwordStr】:"+passwordStr);
            userInfo.setPassword(passwordStr);

            //登录前，先检查账号有没有被锁定
            MessageVO checkLockMessage = iOperateUserInfoServiceClient.getOperateAccountLockDetail(userInfo.getUserName());
            if (checkLockMessage != null) {
                request.setAttribute("checkMessage",checkLockMessage);
                return checkLockMessage;
            }

            //登陆后的用户信息
            OperateUserInfoPO loginUser=iOperateUserInfoServiceClient.login(userInfo);
            UserLoginLogPO userLog=new UserLoginLogPO();        //用户登录日志实体类
            if(loginUser==null){
                userLog.setAccount(userInfo.getUserName());
                userLog.setIp(HttpProtocolUtil.getIpAddr(request));
                userLog.setSystemType(SystemTypeEnum.OPERATE.getType());
                messageVO=new MessageVO(OperateErrorCodeEnum.USER_LOGIN_ERROE.getErrorCode());
                //记录用户登录日志
                userLog.setDescription(UserLoginDescEnum.PASSWORDERROR.getDescription());
                request.setAttribute("userLog",userLog);

                //账号或密码错误，累计5次
                messageVO = iOperateUserInfoServiceClient.loginErrorHandler(userInfo);
                request.setAttribute("checkMessage",messageVO.getMsg());
                return messageVO;

            }else {
                //判断账号下是否只有工程人员
                String roleIds[] = StringHandlerUtil.splitString(loginUser.getRoleId());
                if(roleIds.length==0){
                    return new MessageVO(OperateErrorCodeEnum.USER_LOGIN_ROLE_AUTH.getErrorCode());
                }
                if(roleIds.length==1 && roleIds[0].equals("1")){
                    return new MessageVO(OperateErrorCodeEnum.PUB_LOGIN_ACCOUNT_IS_NOT_EXIST.getErrorCode());
                }
                OperateUserLoginVO loginVO=new OperateUserLoginVO();
                userLog.setAccount(loginUser.getUserName());
                userLog.setRealName(loginUser.getRealName());
                userLog.setIp(HttpProtocolUtil.getIpAddr(request));
                userLog.setSystemType(SystemTypeEnum.OPERATE.getType());
                loginVO.setToken(loginUser.getToken());
                loginVO.setRoleName(loginUser.getRoleName());
                loginVO.setMyUserName(loginUser.getUserId());
                loginVO.setRealName(loginUser.getRealName());
                SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                loginVO.setPasswordTime(df.format(loginUser.getPasswordTime()));
                //记录用户登录日志
                userLog.setDescription(UserLoginDescEnum.SUCCESS.getDescription());
                request.setAttribute("userLog",userLog);
                messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), loginVO);
            }
            //保存用户登陆日志
//            iUserLoginLogServiceClient.saveBuild(userLog);
        }catch (Exception e){
            throw new DataAccessException("【运营_系统_用户login】用户登陆失败",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      修改密码
     * </desc>
     *
     * @param token 用户名
     * @param password 密码
     * @param newPassword 新密码
     * @return
     * @author Jiaqi.X
     * @createDate 2017/10/13
     */
    @LoggerInfo(operateDesc = LogDescConstant.USER_OPERATE_LOG_UPDATEPASSWORD)
    @RequestMapping(path = "updatePassword",method = RequestMethod.POST)
    @ResponseBody
    public Object updatePassword(String token,String password,String newPassword){
        MessageVO messageVO;
        try{
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            token=request.getAttribute("token")==null?null:request.getAttribute("token").toString();
            password=request.getAttribute("password")==null?null:request.getAttribute("password").toString();
            newPassword=request.getAttribute("newPassword")==null?null:request.getAttribute("newPassword").toString();
            OperateUserInfoPO userInfo=iOperateUserInfoServiceClient.retrieve(token);
            //解密密码
            newPassword = UserTokenUtil.getPassword(newPassword,userPasswordKey);
            password = UserTokenUtil.getPassword(password,userPasswordKey);
            //根据userId 原密码判断原密码是否正确，不能使用缓存中的密码进行校验
            List<OperateUserInfoPO> userInfoPO = iOperateUserInfoServiceClient.isUserOldPsdExist(userInfo.getUserId(),Md5EncryptUtil.md5(password));
            if(userInfoPO == null || userInfoPO.isEmpty()){
                //密码错误提示
                return new MessageVO(OperateErrorCodeEnum.USER_UPDATE_PASSWORD.getErrorCode());
            }
            if(Md5EncryptUtil.md5(newPassword).equals(userInfoPO.get(0).getPassword())){
                //新旧密码不能相同提示
                return new MessageVO(OperateErrorCodeEnum.USER_UPDATE_PASSWORD_SAME.getErrorCode());
            }
            Integer result=iOperateUserInfoServiceClient.updatePassword(userInfo.getUserName(),password,newPassword);
            if(result!=null) {
                messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
            }else{
                //密码错误提示
                return new MessageVO(OperateErrorCodeEnum.USER_UPDATE_PASSWORD.getErrorCode());
            }
        }catch (Exception e){
            throw new DataAccessException("【运营_系统_用户cancel】修改密码失败",e);
        }
        return messageVO;
    }


    /**
     * <desc>
     *      注销
     * </desc>
     *
     * @param token
     * @return
     * @author Jiaqi.X
     * @createDate 2017/10/13
     */
    @RequestMapping(path = "logout",method = RequestMethod.POST)
    @ResponseBody
    public Object cancel(String token,HttpServletRequest request){
        MessageVO messageVO;
        try{
            token=request.getAttribute("token")==null?null:request.getAttribute("token").toString();
            //记录用户登陆日志
            OperateUserInfoPO userInfo=iOperateUserInfoServiceClient.retrieve(token);
            if(userInfo!=null && StringUtils.isNotBlank(userInfo.getUserId())) {
                UserLoginLogPO userLog = new UserLoginLogPO();
                userLog.setAccount(userInfo.getUserName());
                userLog.setRealName(userInfo.getRealName());
                userLog.setIp(HttpProtocolUtil.getIpAddr(request));
                userLog.setSystemType(SystemTypeEnum.OPERATE.getType());
                userLog.setDescription(UserLoginDescEnum.CANCEL.getDescription());
                iOperateUserInfoServiceClient.cancel(token);
                iUserLoginLogServiceClient.save(userLog);
            }
            messageVO=new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        }catch (Exception e){
            throw new DataAccessException("【运营_系统_用户cancel】用户注销失败",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      获取缓存用户DEMO
     * </desc>
     *
     * @param token
     * @return
     * @author Jiaqi.X
     * @createDate 2017/10/13
     */
    @RequestMapping(path = "retrieve",method = RequestMethod.POST)
    @ResponseBody
    public Object retrieve(String token){
        MessageVO messageVO;
        try{
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            token=request.getAttribute("token")==null?null:request.getAttribute("token").toString();
            OperateUserInfoPO operateUserInfoPO=iOperateUserInfoServiceClient.retrieve(token);
            messageVO=new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),operateUserInfoPO);
        }catch (Exception e){
            throw new DataAccessException("【运营_系统_用户retrieve】获取缓存用户失败",e);
        }
        return messageVO;
    }

}
